package com.xuyn.framework.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.xuyn.framework.aspectj.DataSourceType;
import com.xuyn.framework.config.properties.DruidProperties;
import com.xuyn.framework.datasource.DynamicDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @ Program     : xuyn
 * @ Description : druid 配置多数据源
 * @ Author      : Emason
 * @ Create      : 2019-09-19 14:35
 * @ Since       : 1.0
 **/
@Configuration
public class DruidConfig {

    /**
     * 主数据源
     * @param druidProperties
     * @return
     */
    @Bean
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource(DruidProperties druidProperties){
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    /**
     *  @ConditionalOnProperty(prefix = "...", name = "enabled", havingValue = "true")
     *  prefix: application-druid.yml 配置的前缀
     *  name:   属性是从 application-druid.yml 配置文件中读取属性值
     *  havingValue 配置读取的属性值跟havingValue做比较，如果一样则返回true;否则返回false。
     *              如果返回值为false，则该configuration不生效；为true则生效
     */
    @Bean
    @ConfigurationProperties("spring.datasource.druid.slave")
    @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
    public DataSource slaveDataSource(DruidProperties druidProperties){
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    /**
     * @Primary ： 自动装配 @Autowired 时当出现多个Bean候选者时，被注解为@Primary的Bean将作为首选者，
     *             否则将抛出异常
     */
    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource, DataSource slaveDataSource){
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
        targetDataSources.put(DataSourceType.SLAVE.name(), slaveDataSource);
        return new DynamicDataSource(masterDataSource, targetDataSources);
    }
}
